旧游无处不堪寻
无寻处,惟有少年心
『计算机的组成与设计』-计算机的算数运算

当你少年时,你的压力,生活的烦恼,没有人理解,
当你成人了,你的压力,生活的烦恼,每个人都懂。
但没有人在乎。

算数逻辑单元(ALU)


可执行的运算包括:

  1. 算术运算
  2. 逻辑运算

算数运算

要注意: 在执行立即数加法时,imm 是 16 位。而寄存器是 32 位,这就出现转换的问题。在手册中是使用 imm 的符号扩展,也就是将高 16 位采用低 16 位的最高位复制 16 次进行填充。(符号扩展不会改变原数值)。

逻辑运算

对于逻辑运算,在执行立即数逻辑运算时,也需要对 imm 进行扩展,但是采用的不是符号扩展而是零扩展。也就是将高 16 位全部用 0 填充。

门电路的基本原理


逻辑门是数字电路的基本组成部分,门是一个电子设备,用于计算二值信号上的函数,常使用晶体管组合而成。
逻辑门的输入被设计仅接收电压输入二进制数据(低 0 或高 1)。
通过组合逻辑门,我们可以设计许多特定的电路,如触发器、锁存器、多路复用器、移位寄存器等。

晶体管(三极管,transistor)

现在集成电路中通常使用 MOS 晶体管。

MOS 分为三部分 Source,Drain 和 Gate。
MOS 相当于水龙头,Source 相当于入水口,Drain 相当于出水口,Gate 相当于水闸。
MOS 分成2种:

  1. N 型 MOS
    导通条件是 Gate 端连接高电平。
  2. P 型 MOS
    导通条件是 Gate 端连接低电平。

CMOS 集成电路

由 PMOS 和 NMOS 共同构成的互补型 MOS 集成电路称为 CMOS。
CMOS 逻辑器件也被称为 3.3 伏器件,因为 CMOS 器件的最大电压电平为 3.3V。这是一种先进技术,可在低电源(3.3V 而不是 5V)下运行器件。

非门(NOT gate)

有一个输入,有一个输出。

真值表

输入 A 输出 Y
0 1
1 0

逻辑函数表示

Y= ~A 或 Y = !A

与门(AND gate)

有两个输入,有一个输出。

真值表

输入 A 输入 B 输出 Y
0 0 0
1 0 0
0 1 0
1 1 1

逻辑函数表示

Y= A.B
注意: 实际使用 与非门 与 非门 结合成 与门。

或门(OR gate)

有两个输入,有一个输出。

真值表

输入 A 输入 B 输出 Y
0 0 0
1 0 1
0 1 1
1 1 1

逻辑函数表示

Y= A+B
注意: 实际使用 或非门 与 非门 结合成 或门。

异或门(XOR gate)

有两个输入,有一个输出。

真值表

输入 A 输入 B 输出 Y
0 0 0
1 0 1
0 1 1
1 1 0

逻辑函数表示

Y= A^B

基本 CMOS 逻辑门

寄存器的基本原理


在 CPU 内部,存储信息的重要部件就是寄存器。

D 触发器(DFF)

  • 具有存储信息能力的基本单元
  • 由若干逻辑门构成,有多种实现方式
  • 有一个数据输入,一个数据输出,一个时钟输入

在时钟 clock 的上升沿(0-1),采样输入 D 的值,传送到输出 Q,其余时间,输出 Q 不变。

寄存器的构成

将多个 D 触发器组合就形成了寄存器。

逻辑运算的实现


与门 和 与运算的实现

需要 32 个与门,将第一个 32 位的源操作数中的每一位都连接到一个与门的第一个输入(从 A0-A31),并将第二个 32 位的源操作数中的每一位都连接到一个与门的第二个输入(从 B0-B31),将 32 个与门的输出都连接到32位目的操作数的每一位(从 Y0-Y31)。

或门 和 或运算的实现

需要 32 个或门,将第一个 32 位的源操作数中的每一位都连接到一个或门的第一个输入(从 A0-A31),并将第二个 32 位的源操作数中的每一位都连接到一个或门的第二个输入(从 B0-B31),将 32 个或门的输出都连接到 32 位目的操作数的每一位(从 Y0-Y31)。

ALU 种包含多种逻辑和算术运算单元。原理是: 外面有两个输入端口,分别与内部不同的运算单元的不同输入端口连接,按照不同的功能,完成不同的操作。再通过多选器,产生一个 32 位的输出。

算术运算的实现

二进制加法

  • 两个 1-bit 二进制数相加
  • 进位输入参与运算
  • 可以产生进位输出

半加器(Half Adder)

半加器的功能是将两个一位二进制数相加。由一个异或门与门组成。

  • 输入端口 A 和 B
  • 输出端口 S(和)和 C(进位)

全加器(Full Adder)

全加器由两个半加器组成。

  • 输入端口 A,B 和 Cin(进位输入)
  • 输出端口 S(和)和 Cout(进位输出)

区别: 半加器能产生进位但是不能处理进位,而全加器可以
注意: 我们要做几位的加法器,就是用几个全加器串联,使后一个全加器的进位输出作为前一个全加器的进位输入。(会有性能问题,之后会改进)

溢出(overflow)


运算结果超出了正常的表示范围。

溢出仅针对有符号数运算

  • 两个正数相加,结果为负数
  • 两个负数相加,结果为正数

注意区分进位和溢出

溢出的检查方法

最高位的进位输入,不等于最高位的进位输出。
把最高位的进位输入和最高位的进位输出连接一个 XOR 就可以判断 overflow。

MIPS 对 overflow 的处理

提供两类指令分别处理:

  1. 将操作数看作有符号数,发生 overflow 时产生异常
    如: add 和 addi 指令
  2. 将操作数看作无符号数,不处理 overflow
    如: addu 和 addui 指令

异常: 也叫中断,一种打断正常程序执行过程的事件。
中断: 来自处理器外部的异常(在某些体系结构中,多有的异常都称为中断)
从本质上来说,异常或中断是一种打断正常过程的系统调用,产生溢出的指令地址保存在一个寄存器中,而后计算机回调到一个预先设定好的地址去执行相应的异常处理程序。保存异常地址的目的是为了在某些条件下能够在异常处理程序执行完后返回原程序继续执行。
MIPS 使用命名为异常程序计数器 Exception Program Counter,EPC的寄存器来保存导致异常的指令地址。

减法运算


减法运算都可以转化为加法运算

A - B = A + (-B)

在计算机中负数是使用补码表示的。

转换规则: 按位取反,末位加 1。

x : 01001011
~x: 10110100
+
-------------
-1 11111111

x + (~x) = -1
-x = (~x) + 1

在加法器的基础上实现减法器

A + (-B) = A + (~B + 1)
在 B 端口加一个 2 选 1 的多选器。

加法器的改进


行波进位加法器

之前我们将全加器串联得到的加法器称为行波进位加法器(RCA)
结构特点
低位全加器 Cout连接到高一位的全加器 Cin
优点
电路布局简单,设计方便
缺点
高位的运算必须等低位运算完成,延迟时间长

超前进位加法器

超前进位加法器(carry look ahead adder,CLA)是对普通的全加器进行改良而设计成的并行加法器,主要是针对普通全加器串联时互相进位产生的延迟进行了改良。超前进位加法器是通过增加了一个不是十分复杂的逻辑电路来做到这点的。
结构特点
每一次的进位都和之前的进位无关,与之前的位输入以及第一个 Cin有关。而这些结果是可以通过一个时钟周期就计算出来的。

乘法器

二进制的乘法器(multiplier)是数字电路的一种元件,它可以将两个二进制数相乘,乘法器是由更基本的加法器组成的。

N位乘法器工作流程

  • 基本流程

基本流程

  • 优化流程

优化流程

N位乘法器实现

  • 基本实现

基本实现

  • 优化实现

优化实现

浮点数


除了整数,编程语言也支持带小数的数字。

浮点表示

浮点表示的设计者必须在尾数和指数之间找到折中的颁发。折中是在精度和表示范围间进行权衡: 增加小数部分会增加精度,增加指数部分会增加表示范围。好的设计需要折中

MIPS 的单精度浮点数(float)表示如下:

  • 右边 1 位表示符号
  • 之后 8 位表示指数域
  • 在之后 23 位表示尾数域

浮点数会出现一种新的溢出: 下溢
下溢发生的条件是: 负指数太大为不能在指数域中表示。
减少下溢的方法是采用更大的指数格式。称为双精度浮点数(double),由两个 32 位的字组成。
MIPS 的双精度浮点数(double)表示如下:

  • 右边 1 位表示符号
  • 之后 11 位表示指数域
  • 在之后 52 位表示尾数域